<?php


namespace app\common\controller;

class MathCaptcha {
    private $width = 120;
    private $height = 40;
    private $fontFile = '';
    private $sessionKey = '';

    public function __construct($width = 120, $height = 40) {
        $this->width = $width;
        $this->height = $height;
        // 设置字体文件路径，请确保这个字体文件存在
        $this->fontFile = __DIR__ . '/arial.ttf'; // 替换为您自己的字体文件路径

        if (!file_exists($this->fontFile)) {
            // 如果没有字体文件，使用默认的GD字体
            $this->fontFile = null;
        }

        $this->sessionKey = time().'_'.rand(10000,999999);

        // 启动session（如果尚未启动）
        if (session_status() == PHP_SESSION_NONE) {
            session_start();
        }
    }

    /**
     * 生成验证码
     * @return array 包含base64图片和key的数组
     */
    public function generate() {
        // 创建画布
        $image = imagecreate($this->width, $this->height);

        // 设置颜色
        $backgroundColor = imagecolorallocate($image, 255, 255, 255);
        $textColor = imagecolorallocate($image, 0, 0, 0);
        $noiseColor = imagecolorallocate($image, 100, 100, 100);

        // 填充背景
        imagefill($image, 0, 0, $backgroundColor);

        // 添加干扰线
        for ($i = 0; $i < 5; $i++) {
            imageline($image,
                rand(0, $this->width),
                rand(0, $this->height),
                rand(0, $this->width),
                rand(0, $this->height),
                $noiseColor
            );
        }

        // 添加干扰点
        for ($i = 0; $i < 100; $i++) {
            imagesetpixel($image,
                rand(0, $this->width),
                rand(0, $this->height),
                $noiseColor
            );
        }

        // 生成数学表达式
        $expression = $this->generateMathExpression();
        $captchaText = $expression['question'];
        $captchaKey = $expression['answer'];

        // 存储验证码答案到session
        $_SESSION[$this->sessionKey] = $captchaKey;

        // 在图片上写入文本
        if ($this->fontFile) {
            // 使用TrueType字体
            $fontSize = 16;
            $textBbox = imagettfbbox($fontSize, 0, $this->fontFile, $captchaText);
            $textWidth = $textBbox[2] - $textBbox[0];
            $textHeight = $textBbox[1] - $textBbox[7];

            $x = ($this->width - $textWidth) / 2;
            $y = ($this->height + $textHeight) / 2;

            imagettftext($image, $fontSize, 0, $x, $y, $textColor, $this->fontFile, $captchaText);
        } else {
            // 使用内置字体
            $font = 5;
            $textWidth = imagefontwidth($font) * strlen($captchaText);
            $textHeight = imagefontheight($font);

            $x = ($this->width - $textWidth) / 2;
            $y = ($this->height - $textHeight) / 2;

            imagestring($image, $font, $x, $y, $captchaText, $textColor);
        }

        // 输出为base64
        ob_start();
        imagepng($image);
        $imageData = ob_get_clean();
        $base64 = 'data:image/png;base64,' . base64_encode($imageData);

        // 释放内存
        imagedestroy($image);

        return [
            'image' => $base64,
            //'captchaText'=>$captchaText,
            //'captchaKey'=>$captchaKey,
            'key' => $this->sessionKey // 返回key名称，实际值存储在session中
        ];
    }

    /**
     * 生成数学表达式
     * @return array 包含问题和答案的数组
     */
    private function generateMathExpression() {
        $operators = ['+', '-', '*'];
        $operator = $operators[array_rand($operators)];

        switch ($operator) {
            case '+':
                $num1 = rand(1, 20);
                $num2 = rand(1, 20);
                $answer = $num1 + $num2;
                break;
            case '-':
                $num1 = rand(10, 30);
                $num2 = rand(1, $num1); // 确保结果为正数
                $answer = $num1 - $num2;
                break;
            case '*':
                $num1 = rand(1, 9);
                $num2 = rand(1, 9);
                $answer = $num1 * $num2;
                break;
            default:
                $num1 = rand(1, 20);
                $num2 = rand(1, 20);
                $answer = $num1 + $num2;
        }

        $question = "{$num1} {$operator} {$num2} = ?";

        return [
            'question' => $question,
            'answer' => $answer
        ];
    }

    /**
     * 验证用户输入
     * @param string $userInput 用户输入的答案
     * @return bool 验证结果
     */
    public function validate($userInput) {
        if (!isset($_SESSION[$this->sessionKey])) {
            return false;
        }

        $storedAnswer = $_SESSION[$this->sessionKey];

        // 验证后清除session，防止重复使用
        unset($_SESSION[$this->sessionKey]);

        return intval($userInput) === $storedAnswer;
    }

    /**
     * 获取当前存储的验证码答案（用于调试）
     * @return mixed 验证码答案
     */
    public function getStoredAnswer() {
        return $_SESSION[$this->sessionKey] ?? null;
    }
}